<?php
abstract class Engine_Form {

    protected $action;
    protected $elements;
    protected $type;
    protected $params;
    protected $attribs;
    protected $errors = array();
    protected $name = 'default';

    abstract public function init();

    public function getElement($name, $default=false) {
     if (array_key_exists($name,$this->elements)){
         return $this->elements[$name];
     }  else {
         return $default;
     }
    }

    public function __construct( $name = false, $params = array(), $type= 'post') {
        if ($name) $this->setName($name);
        $this->type=$type;
        $this->setParams($params);
        $this->init();
    }

    public function getElements(){
        return $this->elements;
    }

    public function getAction(){
        return $this->action;
    }

    public function getAttribs(){
        return $this->attribs;
    }

    public function getAttrib($name, $default=false){
        if (array_key_exists($name,$this->attribs)){
            return $this->attribs[$name];
        }  else {
            return $default;
        }
    }

    public function getName(){
         return $this->name;
    }

    public function getParam($name,$default=false){
     if (array_key_exists($name,$this->params)){
            return $this->params[$name];
        }  else {
            return $default;
        }
    }

    public function getParams(){
        return $this->params;
    }

    public function setName($name) {
        $this->name=$name;
    }

    public function setParam($name,$value){
        $this->params[$name]=$value;
    }

    public function setParams($params){
        foreach ($params as $key=>$param){
            $this->setParam($key,$param);
        }
    }

    public function setAttrib($name, $value){
        $this->attribs{$name}= $value;
    }

    public function setAttribs($attribs){
        foreach ($attribs as $key=>$attrib){
            $this->setAttrib($key,$attrib);
        }
    }

    public function addElement(Engine_Form_Element $element){
        $this->elements[$element->getName()] = $element;
    }

    public function removeElement($name){
        unset($this->elements[$name]);
    }

    public function addError($text) {
        $this->errors[] = $text;
    }

    public function isValid($data = null){
        $result = true;
        $data = $data ? $data : $this->getValues();
        if (is_array($this->elements) && !empty($this->elements)) {
            foreach ($this->elements as $element) {
                if (!$element->isValid($data))
                    $result = false;
            }
        }
        return $result;
    }

    public function renderAttribs() {
        $attribs = $this->getAttribs();
        $result = '';
        if (is_array($attribs) && !empty($attribs)) {
            foreach ($attribs as $key=>$value)
                $result .= ' ' . $key . ' = "' . $value . '"';
        }
        return $result;
    }

    public function __toString() {

        $result = '<form class="form-' . $this->name . '" method="' . $this->type . '" action = "' . $this->action . '" ' . $this->renderAttribs() . ' >' ;
        if ($formName = $this->getParam('name')){
            $result .= '<h2 class="form-signin-heading">' . $formName . '</h2>';
        }
        $result .= Engine_View_Helper_Bootstrap::error($this->errors);
        $elements = $this->getElements();
        if (is_array($elements) && !empty($elements))
        {
            foreach ($elements as $element) {
                $result .= $element->render();
            }
        }
        $result .= '</form>';

        return $result;
    }

    public function populate($params) {
        $elements = $this->getElements();
        if (is_array($elements) && !empty($elements) && !empty($params))
        {
            foreach ($elements as $element) {
                if ($element->getName()!=null && array_key_exists($element->getName(), $params)){
                    $element->setValue($params[$element->getName()]);
                }
            }
        }
    }

    public function getValues() {
        $result = array();
        $elements = $this->getElements();
        if (is_array($elements) && !empty($elements)) {
            foreach ($elements as $element) {
                $result[$element->getName()] = $element->getValue();
            }
        }
        return $result;
    }

}